15. Idling Resource Code Sample - Part 2

Idling Resource Code Sample - Part 2

I recommend opening the code from the link below and exploring the files along with me.

Find Code Here

Here’s what the app looks like when it runs:

Type in EditText field > Click button > Delay message > TextView displays typed message

Type in EditText field > Click button > Delay message > TextView displays typed message

MainActivity.java

Navigate to MainAcitivity.java. In the MainActivity class we get a text String from the user and display it after a delay.

MainActivity extends from the Activity class and implements both View.onClickListener (created by the Android framework) and Message.Delayer.DelayerCallback (created in this project).

Next we declare the TextView and EditText view which are setup in onCreate().

We also declare a private variable called mIdlingResource of type SimpleIdlingResource. Notice that it has an annotation @Nullable which indicates that this variable will be null in production. This is because this setup with IdlingResource is only used for testing, so when the project is run in production, IdlingResource can be null.

MainActivity.java - Declare variables and onCreate()

MainActivity.java - Declare variables and onCreate()

When the changeTextBt is clicked, onClick() retrieves the text the user typed in the EditText view, sets a temporary waiting message, and then submits the user-entered EditText value to the processMessage() method of MessageDelayer.java.

MainActivity.java onClick() method

MainActivity.java onClick() method

MessageDelayer.java

This class is not part of the Android framework. It was created for this project. It takes a String and returns it after a delay via a callback. It executes a long-running operation on a different thread that will cause problems with Espresso if IdlingResource is not implemented and registered.

The processMessage() method takes a String (the one that the user typed into the EditText field), and returns it after the delay time we setup in DELAY_MILLIS. The String is returned via the callback in the onDone method.

MessageDelayer.java processMessage() method

MessageDelayer.java processMessage() method

processMessage() has 3 parameters - the message, the activity to return back to in the callback, and the IdlingResource.

The if statement checks whether or not IdlingResource is null. If it isn’t we can go ahead and set idle to false. Remember that idle means:

  • No UI events in the current message queue
  • No more tasks in the default AsyncTask thread pool

So if idle is false there are tasks or events that are happening and any testing should be on halt until these processes finish.

With idle set as false we create a handler and run the method postDelayed().

What exactly is a Handler and what’s the purpose of postDelayed()?

Handler

If we look in the Developer documentation, we can see that there are 2 main uses for a Handler:

Developer doc for Handler class

Developer doc for Handler class

Further down in the code we see that postDelayed() adds a Runnable to a message queue and it will run after a specified amount of time.

Developer doc for postDelayed() method in Handler class

Developer doc for postDelayed() method in Handler class

The first parameter of postDelayed() is the Runnable that will be run once the delay time is up. So what do we expect to run?

handler.postDelayed() has 2 parameters - a Runnable and a time delay

handler.postDelayed() has 2 parameters - a Runnable and a time delay

The first action of the Runnable is to check the callback we received in processMessage() (i.e. which activity we should return to after the delay). We return to that activity’s onDone() method and return the message variable.

Then we check that idlingResource is not null. If it's not null we set its state to true. Remember that if the app is idle it means that Espresso gets the green light and continues any action in the test that was queued.

The second parameter, delay time, is set to the constant DELAY_MILLIS in MessageDelayer.java:

Delay time set in MessageDelayer.java

Delay time set in MessageDelayer.java

Summary

Let's take a pause and recap what we've uncovered so far.

When the changeTextBt is clicked, onClick() in MainActivity triggers MessageDelayer.processMessage().

processMessage() sets the IdlingResource to false, then creates a Handler which contains a Runnable that will be run after a pre-determined time delay, DELAY_MILLIS.
The Runnable that will be executed after the delay:

1) Returns the String entered by the user via a callback to the calling activity (e.g. MainActivity)

2) Sets the IdlingResource to true


Learn More About:

@Nullable

Handler

Runnable

Espresso Idling Resource